// @Author yang
// @Description 
// @Date 2021/7/28
// @Time 9:50

package demo

import (
	uuid "github.com/satori/go.uuid"
	"sync"
)

type SafeRWObj struct {
	Obj    interface{}   // 保存的数据
	rwLock *sync.RWMutex // 行锁
}

func NewSafeObj(obj interface{}) *SafeRWObj {
	return &SafeRWObj{
		Obj:    obj,
		rwLock: new(sync.RWMutex),
	}
}

func (this *SafeRWObj) Get() interface{} {
	this.rwLock.RLock()
	defer this.rwLock.RUnlock()
	return this.Obj
}

func (this *SafeRWObj) Set(obj interface{}) {
	this.rwLock.Lock()
	defer this.rwLock.Unlock()
	this.Obj = obj
}

// 对象层次的安全操作包装
type SafeOpsObj interface {
	Get() interface{}
	Set(obj interface{})
}

type SafeMap struct {
	mp     map[string]SafeOpsObj // 存放数据
	rwlock *sync.RWMutex         // 表锁
}

func NewSafeMap() *SafeMap {
	return &SafeMap{
		mp:     map[string]SafeOpsObj{},
		rwlock: new(sync.RWMutex),
	}
}

func (this *SafeMap) Get(key string) SafeOpsObj {
	this.rwlock.RLock()
	defer this.rwlock.RUnlock()
	return this.mp[key]
}

func (this *SafeMap) Set (key string, obj SafeOpsObj)  {
	this.rwlock.Lock()
	defer this.rwlock.Unlock()
	this.mp[key] = obj
}

func main() {
	safeMap := NewSafeMap()
	for true {
		go func() {
			safeMap.Set(uuid.NewV4().String(), NewSafeObj())
		}()
	}
}
